if (!finfo)
goto out;
- if (S_ISREG (g_file_info_get_attribute_uint32 (finfo, "unix::mode")))
+ if (g_file_info_get_file_type (finfo) == G_FILE_TYPE_REGULAR)
{
instream = (GInputStream*)g_file_read (file, cancellable, error);
if (!instream)
gboolean
ostree_parse_packed_file (GFile *file,
- GVariant **out_metadata,
- GInputStream **out_content,
- GCancellable *cancellable,
- GError **error)
+ GFileInfo **out_file_info,
+ GVariant **out_xattrs,
+ GInputStream **out_content,
+ GCancellable *cancellable,
+ GError **error)
{
gboolean ret = FALSE;
char *metadata_buf = NULL;
- GVariant *ret_metadata = NULL;
- GFileInputStream *in = NULL;
+ GVariant *metadata = NULL;
+ GFileInfo *ret_file_info = NULL;
+ GVariant *ret_xattrs = NULL;
+ GInputStream *in = NULL;
guint32 metadata_len;
+ guint32 version, uid, gid, mode;
+ guint64 content_len;
gsize bytes_read;
- in = g_file_read (file, NULL, error);
+ in = (GInputStream*)g_file_read (file, NULL, error);
if (!in)
goto out;
- if (!g_input_stream_read_all ((GInputStream*)in, &metadata_len, 4, &bytes_read, NULL, error))
+ if (!g_input_stream_read_all (in, &metadata_len, 4, &bytes_read, NULL, error))
goto out;
if (bytes_read != 4)
{
}
metadata_buf = g_malloc (metadata_len);
- if (!g_input_stream_read_all ((GInputStream*)in, metadata_buf, metadata_len, &bytes_read, NULL, error))
+ if (!g_input_stream_read_all (in, metadata_buf, metadata_len, &bytes_read, NULL, error))
goto out;
if (bytes_read != metadata_len)
{
goto out;
}
- ret_metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
- metadata_buf, metadata_len, FALSE,
- (GDestroyNotify)g_free,
- metadata_buf);
+ metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
+ metadata_buf, metadata_len, FALSE,
+ (GDestroyNotify)g_free,
+ metadata_buf);
metadata_buf = NULL;
+ g_variant_get (metadata, "(uuuu@a(ayay)t)",
+ &version, &uid, &gid, &mode,
+ &ret_xattrs, &content_len);
+ uid = GUINT32_FROM_BE (uid);
+ gid = GUINT32_FROM_BE (gid);
+ mode = GUINT32_FROM_BE (mode);
+ content_len = GUINT64_FROM_BE (content_len);
+
+ ret_file_info = g_file_info_new ();
+ g_file_info_set_attribute_uint32 (ret_file_info, "standard::type", ot_gfile_type_for_mode (mode));
+ g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", S_ISLNK (mode));
+ g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", uid);
+ g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", gid);
+ g_file_info_set_attribute_uint32 (ret_file_info, "unix::mode", mode);
+ g_file_info_set_attribute_uint64 (ret_file_info, "standard::size", content_len);
+
+ if (S_ISREG (mode))
+ {
+ g_file_info_set_attribute_uint64 (ret_file_info, "standard::size", content_len);
+ }
+ else if (S_ISLNK (mode))
+ {
+ char target[PATH_MAX+1];
+ if (!g_input_stream_read_all (in, target, sizeof(target)-1, &bytes_read, cancellable, error))
+ goto out;
+ target[bytes_read] = '\0';
+
+ g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", TRUE);
+ g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", target);
+
+ g_input_stream_close (in, cancellable, error);
+ g_clear_object (&in);
+ }
+ else if (S_ISCHR (mode) || S_ISBLK (mode))
+ {
+ guint32 dev;
+
+ if (!g_input_stream_read_all (in, &dev, 4, &bytes_read, NULL, error))
+ goto out;
+ if (bytes_read != 4)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Corrupted packfile; too short while reading device id");
+ goto out;
+ }
+ dev = GUINT32_FROM_BE (dev);
+ g_file_info_set_attribute_uint32 (ret_file_info, "unix::rdev", dev);
+ g_input_stream_close (in, cancellable, error);
+ g_clear_object (&in);
+ }
+ else if (S_ISFIFO (mode))
+ {
+ g_input_stream_close (in, cancellable, error);
+ g_clear_object (&in);
+ }
+ else
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Corrupted packfile; invalid mode %u", mode);
+ goto out;
+ }
+
ret = TRUE;
- *out_metadata = ret_metadata;
- ret_metadata = NULL;
- *out_content = (GInputStream*)in;
- in = NULL;
+ if (out_file_info)
+ {
+ *out_file_info = ret_file_info;
+ ret_file_info = NULL;
+ }
+ if (out_xattrs)
+ {
+ *out_xattrs = ret_xattrs;
+ ret_xattrs = NULL;
+ }
+ if (out_content)
+ {
+ *out_content = (GInputStream*)in;
+ in = NULL;
+ }
out:
+ g_clear_object (&ret_file_info);
+ ot_clear_gvariant (&ret_xattrs);
g_clear_object (&in);
- ot_clear_gvariant (&ret_metadata);
+ ot_clear_gvariant (&metadata);
return ret;
}
-static gboolean
-unpack_file (GFile *file,
- GFile *dest_file,
- GChecksum **out_checksum,
- GError **error)
+gboolean
+ostree_create_file_from_input (GFile *dest_file,
+ GFileInfo *finfo,
+ GVariant *xattrs,
+ GInputStream *input,
+ GChecksum **out_checksum,
+ GCancellable *cancellable,
+ GError **error)
{
+ const char *dest_path;
gboolean ret = FALSE;
- GVariant *metadata = NULL;
- GVariant *xattrs = NULL;
- GInputStream *in = NULL;
GFileOutputStream *out = NULL;
+ guint32 uid, gid, mode;
GChecksum *ret_checksum = NULL;
- guint32 version, uid, gid, mode;
- guint64 content_len;
- gsize bytes_read;
- const char *dest_path;
+ uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
+ gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
+ mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode");
dest_path = ot_gfile_get_path_cached (dest_file);
- if (!ostree_parse_packed_file (file, &metadata, &in, NULL, error))
- goto out;
-
- g_variant_get (metadata, "(uuuu@a(ayay)t)",
- &version, &uid, &gid, &mode,
- &xattrs, &content_len);
- uid = GUINT32_FROM_BE (uid);
- gid = GUINT32_FROM_BE (gid);
- mode = GUINT32_FROM_BE (mode);
- content_len = GUINT64_FROM_BE (content_len);
-
if (S_ISREG (mode))
{
out = g_file_replace (dest_file, NULL, FALSE, 0, NULL, error);
if (!out)
goto out;
- if (!ot_gio_splice_and_checksum ((GOutputStream*)out, in, out_checksum ? &ret_checksum : NULL, NULL, error))
+ if (!ot_gio_splice_and_checksum ((GOutputStream*)out, input,
+ out_checksum ? &ret_checksum : NULL,
+ cancellable, error))
goto out;
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
}
else if (S_ISLNK (mode))
{
- char target[PATH_MAX+1];
-
- if (!g_input_stream_read_all (in, target, sizeof(target)-1, &bytes_read, NULL, error))
- goto out;
- target[bytes_read] = '\0';
+ const char *target = g_file_info_get_attribute_byte_string (finfo, "standard::symlink-target");
if (ret_checksum)
- g_checksum_update (ret_checksum, (guint8*)target, bytes_read);
+ g_checksum_update (ret_checksum, (guint8*)target, strlen (target));
if (symlink (target, dest_path) < 0)
{
ot_util_set_error_from_errno (error, errno);
}
else if (S_ISCHR (mode) || S_ISBLK (mode))
{
- guint32 dev;
-
- if (!g_input_stream_read_all (in, &dev, 4, &bytes_read, NULL, error))
- goto out;
- if (bytes_read != 4)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Corrupted packfile; too short while reading device id");
- goto out;
- }
- dev = GUINT32_FROM_BE (dev);
+ guint32 dev = g_file_info_get_attribute_uint32 (finfo, "unix::rdev");
if (ret_checksum)
g_checksum_update (ret_checksum, (guint8*)&dev, 4);
if (mknod (dest_path, mode, dev) < 0)
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Corrupted packfile; invalid mode %u", mode);
+ "Invalid mode %u", mode);
goto out;
}
}
}
- if (!ostree_set_xattrs (dest_file, xattrs, NULL, error))
+ if (!ostree_set_xattrs (dest_file, xattrs, cancellable, error))
goto out;
if (ret_checksum)
ret = TRUE;
if (out_checksum)
- *out_checksum = ret_checksum;
- ret_checksum = NULL;
+ {
+ *out_checksum = ret_checksum;
+ ret_checksum = NULL;
+ }
out:
if (!ret)
(void) unlink (dest_path);
ot_clear_checksum (&ret_checksum);
- g_clear_object (&in);
g_clear_object (&out);
- ot_clear_gvariant (&metadata);
+ return ret;
+}
+
+static gboolean
+unpack_file (GFile *file,
+ GFile *dest_file,
+ GChecksum **out_checksum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GFileInfo *finfo;
+ GVariant *metadata = NULL;
+ GVariant *xattrs = NULL;
+ GInputStream *in = NULL;
+ GChecksum *ret_checksum = NULL;
+
+ if (!ostree_parse_packed_file (file, &finfo, &xattrs, &in, cancellable, error))
+ goto out;
+
+ if (!ostree_create_file_from_input (dest_file, finfo, xattrs, in,
+ out_checksum ? &ret_checksum : NULL,
+ cancellable, error))
+ goto out;
+
+ ret = TRUE;
+ if (out_checksum)
+ {
+ *out_checksum = ret_checksum;
+ ret_checksum = NULL;
+ }
+ out:
+ g_clear_object (&finfo);
ot_clear_gvariant (&xattrs);
+ ot_clear_gvariant (&metadata);
+ ot_clear_checksum (&ret_checksum);
return ret;
}
if (objtype == OSTREE_OBJECT_TYPE_META)
return unpack_meta (file, dest, out_checksum, error);
else
- return unpack_file (file, dest, out_checksum, error);
+ return unpack_file (file, dest, out_checksum, NULL, error);
}
GCancellable *cancellable,
GError **error);
+gboolean ostree_create_file_from_input (GFile *file,
+ GFileInfo *finfo,
+ GVariant *xattrs,
+ GInputStream *input,
+ GChecksum **out_checksum,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean ostree_parse_packed_file (GFile *file,
- GVariant **out_metadata,
- GInputStream **out_content,
- GCancellable *cancellable,
- GError **error);
+ GFileInfo **out_file_info,
+ GVariant **out_xattrs,
+ GInputStream **out_content,
+ GCancellable *cancellable,
+ GError **error);
gboolean ostree_unpack_object (GFile *file,
OstreeObjectType objtype,
{
gboolean ret = FALSE;
GVariant *ret_xattrs = NULL;
- GVariant *metadata = NULL;
- GInputStream *input = NULL;
GFile *local_file = NULL;
if (!_ostree_repo_file_ensure_resolved (self, error))
else if (ostree_repo_is_archive (self->repo))
{
local_file = _ostree_repo_file_nontree_get_local (self);
- if (!ostree_parse_packed_file (local_file, &metadata, &input, cancellable, error))
+ if (!ostree_parse_packed_file (local_file, NULL, &ret_xattrs, NULL, cancellable, error))
goto out;
- ret_xattrs = g_variant_get_child_value (metadata, 4);
}
else
{
ret_xattrs = NULL;
out:
ot_clear_gvariant (&ret_xattrs);
- ot_clear_gvariant (&metadata);
- g_clear_object (&input);
g_clear_object (&local_file);
return ret;
}
return ostree_repo_get_object_path (repo, checksum, OSTREE_OBJECT_TYPE_FILE);
}
-static gboolean
-query_child_info_file_nonarchive (OstreeRepo *repo,
- const char *checksum,
- GFileAttributeMatcher *matcher,
- GFileInfo *info,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean ret = FALSE;
- GFileInfo *local_info = NULL;
- GFile *local_file = NULL;
- int i ;
- const char *mapped_boolean[] = {
- "standard::is-symlink"
- };
- const char *mapped_string[] = {
- };
- const char *mapped_byte_string[] = {
- "standard::symlink-target"
- };
- const char *mapped_uint32[] = {
- "standard::type",
- "unix::device",
- "unix::mode",
- "unix::nlink",
- "unix::uid",
- "unix::gid",
- "unix::rdev"
- };
- const char *mapped_uint64[] = {
- "standard::size",
- "standard::allocated-size",
- "unix::inode"
- };
-
- if (!(g_file_attribute_matcher_matches (matcher, "unix::mode")
- || g_file_attribute_matcher_matches (matcher, "standard::type")))
- {
- ret = TRUE;
- goto out;
- }
-
- local_file = get_child_local_file (repo, checksum);
- local_info = g_file_query_info (local_file,
- OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable,
- error);
- if (!local_info)
- goto out;
-
- for (i = 0; i < G_N_ELEMENTS (mapped_boolean); i++)
- g_file_info_set_attribute_boolean (info, mapped_boolean[i], g_file_info_get_attribute_boolean (local_info, mapped_boolean[i]));
-
- for (i = 0; i < G_N_ELEMENTS (mapped_string); i++)
- {
- const char *string = g_file_info_get_attribute_string (local_info, mapped_string[i]);
- if (string)
- g_file_info_set_attribute_string (info, mapped_string[i], string);
- }
-
- for (i = 0; i < G_N_ELEMENTS (mapped_byte_string); i++)
- {
- const char *byte_string = g_file_info_get_attribute_byte_string (local_info, mapped_byte_string[i]);
- if (byte_string)
- g_file_info_set_attribute_byte_string (info, mapped_byte_string[i], byte_string);
- }
-
- for (i = 0; i < G_N_ELEMENTS (mapped_uint32); i++)
- g_file_info_set_attribute_uint32 (info, mapped_uint32[i], g_file_info_get_attribute_uint32 (local_info, mapped_uint32[i]));
-
- for (i = 0; i < G_N_ELEMENTS (mapped_uint64); i++)
- g_file_info_set_attribute_uint64 (info, mapped_uint64[i], g_file_info_get_attribute_uint64 (local_info, mapped_uint64[i]));
-
- ret = TRUE;
- out:
- g_clear_object (&local_info);
- g_clear_object (&local_file);
- return ret;
-}
-
-static gboolean
-query_child_info_file_archive (OstreeRepo *repo,
- const char *checksum,
- GFileAttributeMatcher *matcher,
- GFileInfo *info,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean ret = FALSE;
- GFile *local_file = NULL;
- GVariant *metadata = NULL;
- GInputStream *input = NULL;
- guint32 version, uid, gid, mode;
- guint64 content_len;
- guint32 file_type;
- gsize bytes_read;
- char *buf = NULL;
-
- local_file = get_child_local_file (repo, checksum);
-
- if (!ostree_parse_packed_file (local_file, &metadata, &input, cancellable, error))
- goto out;
-
- g_variant_get (metadata, "(uuuu@a(ayay)t)",
- &version, &uid, &gid, &mode,
- NULL, &content_len);
- uid = GUINT32_FROM_BE (uid);
- gid = GUINT32_FROM_BE (gid);
- mode = GUINT32_FROM_BE (mode);
- content_len = GUINT64_FROM_BE (content_len);
-
- g_file_info_set_attribute_boolean (info, "standard::is-symlink",
- S_ISLNK (mode));
- if (S_ISLNK (mode))
- file_type = G_FILE_TYPE_SYMBOLIC_LINK;
- else if (S_ISREG (mode))
- file_type = G_FILE_TYPE_REGULAR;
- else if (S_ISBLK (mode) || S_ISCHR(mode) || S_ISFIFO(mode))
- file_type = G_FILE_TYPE_SPECIAL;
- else
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Corrupted packfile %s: Invalid mode", checksum);
- goto out;
- }
- g_file_info_set_attribute_uint32 (info, "standard::type", file_type);
-
- g_file_info_set_attribute_uint32 (info, "unix::uid", uid);
- g_file_info_set_attribute_uint32 (info, "unix::gid", gid);
- g_file_info_set_attribute_uint32 (info, "unix::mode", mode);
-
- if (file_type == G_FILE_TYPE_REGULAR)
- {
- g_file_info_set_attribute_uint64 (info, "standard::size", content_len);
- }
- else if (file_type == G_FILE_TYPE_SYMBOLIC_LINK)
- {
- gsize len = MIN (PATH_MAX, content_len) + 1;
- buf = g_malloc (len);
-
- if (!g_input_stream_read_all (input, buf, len, &bytes_read, cancellable, error))
- goto out;
- buf[bytes_read] = '\0';
-
- g_file_info_set_attribute_byte_string (info, "standard::symlink-target", buf);
- }
- else if (file_type == G_FILE_TYPE_SPECIAL)
- {
- guint32 device;
-
- if (!g_input_stream_read_all (input, &device, 4, &bytes_read, cancellable, error))
- goto out;
-
- device = GUINT32_FROM_BE (device);
- g_file_info_set_attribute_uint32 (info, "unix::device", device);
- }
-
- ret = TRUE;
- out:
- g_free (buf);
- ot_clear_gvariant (&metadata);
- g_clear_object (&local_file);
- g_clear_object (&input);
- return ret;
-}
-
static void
set_info_from_dirmeta (GFileInfo *info,
GVariant *metadata)
}
static gboolean
-query_child_info_dir (OstreeRepo *repo,
- const char *metadata_checksum,
- GFileAttributeMatcher *matcher,
- GFileQueryInfoFlags flags,
- GFileInfo *info,
- GCancellable *cancellable,
- GError **error)
+query_child_info_dir (OstreeRepo *repo,
+ const char *metadata_checksum,
+ GFileAttributeMatcher *matcher,
+ GFileQueryInfoFlags flags,
+ GFileInfo **out_info,
+ GCancellable *cancellable,
+ GError **error)
{
gboolean ret = FALSE;
+ GFileInfo *ret_info = NULL;
GVariant *metadata = NULL;
- if (!g_file_attribute_matcher_matches (matcher, "unix::mode"))
- {
- ret = TRUE;
- goto out;
- }
+ ret_info = g_file_info_new ();
- if (!ostree_repo_load_variant_checked (repo, OSTREE_SERIALIZED_DIRMETA_VARIANT,
- metadata_checksum, &metadata, error))
- goto out;
+ if (g_file_attribute_matcher_matches (matcher, "unix::mode"))
+ {
+ if (!ostree_repo_load_variant_checked (repo, OSTREE_SERIALIZED_DIRMETA_VARIANT,
+ metadata_checksum, &metadata, error))
+ goto out;
- set_info_from_dirmeta (info, metadata);
+ set_info_from_dirmeta (ret_info, metadata);
+ }
ret = TRUE;
+ *out_info = ret_info;
+ ret_info = NULL;
out:
+ g_clear_object (&ret_info);
ot_clear_gvariant (&metadata);
return ret;
}
GVariant *files_variant = NULL;
GVariant *dirs_variant = NULL;
GVariant *tree_child_metadata = NULL;
+ GFile *local_child = NULL;
GFileAttributeMatcher *matcher = NULL;
int c;
matcher = g_file_attribute_matcher_new (attributes);
- ret_info = g_file_info_new ();
-
g_assert (self->tree_contents);
files_variant = g_variant_get_child_value (self->tree_contents, 2);
g_variant_get_child (files_variant, n, "(&s&s)", &name, &checksum);
+ local_child = get_child_local_file (self->repo, checksum);
+
if (ostree_repo_is_archive (self->repo))
{
- if (!query_child_info_file_archive (self->repo, checksum, matcher, ret_info,
- cancellable, error))
- goto out;
+ if (!ostree_parse_packed_file (local_child, &ret_info, NULL, NULL, cancellable, error))
+ goto out;
}
else
{
- if (!query_child_info_file_nonarchive (self->repo, checksum, matcher, ret_info,
- cancellable, error))
- goto out;
+ ret_info = g_file_query_info (local_child,
+ OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable,
+ error);
}
}
else
&name, &tree_checksum, &meta_checksum);
if (!query_child_info_dir (self->repo, meta_checksum,
- matcher, flags, ret_info,
+ matcher, flags, &ret_info,
cancellable, error))
goto out;
}
ret_info = NULL;
out:
g_clear_object (&ret_info);
+ g_clear_object (&local_child);
if (matcher)
g_file_attribute_matcher_unref (matcher);
ot_clear_gvariant (&tree_child_metadata);
#define O_BINARY 0
#endif
+GFileType
+ot_gfile_type_for_mode (guint32 mode)
+{
+ if (S_ISREG (mode))
+ return G_FILE_TYPE_REGULAR;
+ else if (S_ISLNK (mode))
+ return G_FILE_TYPE_SYMBOLIC_LINK;
+ else if (S_ISBLK (mode) || S_ISCHR(mode) || S_ISFIFO(mode))
+ return G_FILE_TYPE_SPECIAL;
+ else
+ return G_FILE_TYPE_UNKNOWN;
+}
+
gboolean
ot_gfile_ensure_directory (GFile *dir,
gboolean with_parents,
#define OSTREE_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,standard::is-hidden,unix::*"
+GFileType ot_gfile_type_for_mode (guint32 mode);
+
GFile *ot_gfile_new_for_path (const char *path);
const char *ot_gfile_get_path_cached (GFile *file);
#include <glib/gi18n.h>
-static gboolean print_packfile;
static gboolean print_compose;
static char* print_variant_type;
static GOptionEntry options[] = {
- { "print-packfile", 0, 0, G_OPTION_ARG_NONE, &print_packfile, "If given, argument given is a packfile", NULL },
{ "print-compose", 0, 0, G_OPTION_ARG_NONE, &print_compose, "If given, show the branches which make up the given compose commit", NULL },
{ "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &print_variant_type, "If given, argument should be a filename and it will be interpreted as this type", NULL },
{ NULL }
return ret;
}
-static gboolean
-do_print_packfile (OstreeRepo *repo,
- const char *checksum,
- GError **error)
-{
- gboolean ret = FALSE;
- GVariant *variant = NULL;
- GInputStream *content = NULL;
- GFile *file = NULL;
-
- file = ostree_repo_get_object_path (repo, checksum, OSTREE_OBJECT_TYPE_FILE);
-
- if (!ostree_parse_packed_file (file, &variant, &content, NULL, error))
- goto out;
-
- print_variant (variant);
-
- ret = TRUE;
- out:
- g_clear_object (&file);
- g_clear_object (&content);
- ot_clear_gvariant (&variant);
- return ret;
-}
-
static gboolean
do_print_compose (OstreeRepo *repo,
const char *rev,
}
rev = argv[1];
- if (print_packfile)
- {
- if (!do_print_packfile (repo, rev, error))
- goto out;
- }
- else if (print_compose)
+ if (print_compose)
{
if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error))
goto out;